/******************************************************************************* * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.jface.action.ContributionItem; import org.eclipse.jface.action.ContributionManager; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.ISourceProvider; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.internal.services.IWorkbenchLocationService; import org.eclipse.ui.internal.services.WorkbenchSourceProvider; import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.menus.IMenuService; import org.eclipse.ui.menus.IWorkbenchContribution; import org.eclipse.ui.menus.MenuUtil; import org.eclipse.ui.part.IShowInSource; import org.eclipse.ui.part.IShowInTargetList; import org.eclipse.ui.part.ShowInContext; import org.eclipse.ui.services.IServiceLocator; import org.eclipse.ui.services.ISourceProviderService; import org.eclipse.ui.views.IViewDescriptor; import org.eclipse.ui.views.IViewRegistry; /** * A <code>ShowInMenu</code> is used to populate a menu manager with Show In * actions. The items to show are determined from the active perspective and * active part. */ public class ShowInMenu extends ContributionItem implements IWorkbenchContribution { // RAP [rh] Cannot reference NLS message from static field // private static final String NO_TARGETS_MSG = WorkbenchMessages.Workbench_showInNoTargets; private final String NO_TARGETS_MSG = WorkbenchMessages.get().Workbench_showInNoTargets; private IWorkbenchWindow window; private Map actions = new HashMap(21); private boolean dirty = true; private IMenuListener menuListener = new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { manager.markDirty(); dirty = true; } }; private IServiceLocator locator; private MenuManager currentManager; public ShowInMenu() { } /** * Creates a Show In menu. * * @param window * the window containing the menu * @param id * The ID for this contribution */ public ShowInMenu(IWorkbenchWindow window, String id) { super(id); this.window = window; } public boolean isDirty() { return dirty; } /** * Overridden to always return true and force dynamic menu building. */ public boolean isDynamic() { return true; } public void fill(Menu menu, int index) { if (getParent() instanceof MenuManager) { ((MenuManager) getParent()).addMenuListener(menuListener); } if (!dirty) { return; } if (currentManager!=null && currentManager.getSize() > 0) { IMenuService service = (IMenuService) locator .getService(IMenuService.class); service.releaseContributions(currentManager); currentManager.removeAll(); } currentManager = new MenuManager(); fillMenu(currentManager); IContributionItem[] items = currentManager.getItems(); if (items.length == 0) { MenuItem item = new MenuItem(menu, SWT.NONE, index++); item.setText(NO_TARGETS_MSG); item.setEnabled(false); } else { for (int i = 0; i < items.length; i++) { if (items[i].isVisible()) { items[i].fill(menu, index++); } } } dirty = false; } /** * Fills the menu with Show In actions. */ private void fillMenu(IMenuManager innerMgr) { // Remove all. innerMgr.removeAll(); IWorkbenchPart sourcePart = getSourcePart(); if (sourcePart == null) { return; } ShowInContext context = getContext(sourcePart); if (context == null) { return; } if (context.getInput() == null && (context.getSelection() == null || context.getSelection() .isEmpty())) { return; } IViewDescriptor[] viewDescs = getViewDescriptors(sourcePart); for (int i = 0; i < viewDescs.length; ++i) { IContributionItem cci = getContributionItem(viewDescs[i]); if (cci != null) { innerMgr.add(cci); } } if (innerMgr instanceof MenuManager) { ISourceProviderService sps = (ISourceProviderService) locator .getService(ISourceProviderService.class); ISourceProvider sp = sps .getSourceProvider(ISources.SHOW_IN_SELECTION); if (sp instanceof WorkbenchSourceProvider) { ((WorkbenchSourceProvider) sp).checkActivePart(true); } IMenuService service = (IMenuService) locator .getService(IMenuService.class); service.populateContributionManager((ContributionManager) innerMgr, MenuUtil.SHOW_IN_MENU_ID); } } /** * Return the appropriate command contribution item for the parameter. * @param viewDescriptor * @return the show in command contribution item */ private IContributionItem getContributionItem(IViewDescriptor viewDescriptor) { CommandContributionItemParameter parm = new CommandContributionItemParameter( locator, viewDescriptor.getId(), IWorkbenchCommandConstants.NAVIGATE_SHOW_IN, CommandContributionItem.STYLE_PUSH); HashMap targetId = new HashMap(); targetId.put(IWorkbenchCommandConstants.NAVIGATE_SHOW_IN_PARM_TARGET, viewDescriptor.getId()); parm.parameters = targetId; parm.label = viewDescriptor.getLabel(); if (parm.label.length() > 0) { parm.mnemonic = parm.label.substring(0, 1); } parm.icon = viewDescriptor.getImageDescriptor(); return new CommandContributionItem(parm); } /** * Returns the Show In... target part ids for the given source part. Merges * the contributions from the current perspective and the source part. */ private ArrayList getShowInPartIds(IWorkbenchPart sourcePart) { ArrayList targetIds = new ArrayList(); WorkbenchPage page = (WorkbenchPage) getWindow().getActivePage(); if (page != null) { targetIds.addAll(page.getShowInPartIds()); } IShowInTargetList targetList = getShowInTargetList(sourcePart); if (targetList != null) { String[] partIds = targetList.getShowInTargetIds(); if (partIds != null) { for (int i = 0; i < partIds.length; ++i) { if (!targetIds.contains(partIds[i])) { targetIds.add(partIds[i]); } } } } page.sortShowInPartIds(targetIds); return targetIds; } /** * Returns the source part, or <code>null</code> if there is no applicable * source part * <p> * This implementation returns the current part in the window. Subclasses * may extend or reimplement. * * @return the source part or <code>null</code> */ private IWorkbenchPart getSourcePart() { IWorkbenchWindow window = getWindow(); if(window == null) return null; IWorkbenchPage page = window.getActivePage(); if (page != null) { return page.getActivePart(); } return null; } /** * Returns the <code>IShowInSource</code> provided by the source part, or * <code>null</code> if it does not provide one. * * @param sourcePart * the source part * @return an <code>IShowInSource</code> or <code>null</code> */ private IShowInSource getShowInSource(IWorkbenchPart sourcePart) { return (IShowInSource) Util.getAdapter(sourcePart, IShowInSource.class); } /** * Returns the <code>IShowInTargetList</code> for the given source part, * or <code>null</code> if it does not provide one. * * @param sourcePart * the source part * @return the <code>IShowInTargetList</code> or <code>null</code> */ private IShowInTargetList getShowInTargetList(IWorkbenchPart sourcePart) { return (IShowInTargetList) Util.getAdapter(sourcePart, IShowInTargetList.class); } /** * Returns the <code>ShowInContext</code> to show in the selected target, * or <code>null</code> if there is no valid context to show. * <p> * This implementation obtains the context from the * <code>IShowInSource</code> of the source part (if provided), or, if the * source part is an editor, it creates the context from the editor's input * and selection. * <p> * Subclasses may extend or reimplement. * * @return the <code>ShowInContext</code> to show or <code>null</code> */ private ShowInContext getContext(IWorkbenchPart sourcePart) { IShowInSource source = getShowInSource(sourcePart); if (source != null) { ShowInContext context = source.getShowInContext(); if (context != null) { return context; } } else if (sourcePart instanceof IEditorPart) { Object input = ((IEditorPart) sourcePart).getEditorInput(); ISelectionProvider sp = sourcePart.getSite().getSelectionProvider(); ISelection sel = sp == null ? null : sp.getSelection(); return new ShowInContext(input, sel); } return null; } /** * Returns the view descriptors to show in the dialog. */ private IViewDescriptor[] getViewDescriptors(IWorkbenchPart sourcePart) { String srcId = sourcePart.getSite().getId(); ArrayList ids = getShowInPartIds(sourcePart); ArrayList descs = new ArrayList(); IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry(); for (Iterator i = ids.iterator(); i.hasNext();) { String id = (String) i.next(); if (!id.equals(srcId)) { IViewDescriptor desc = reg.find(id); if (desc != null) { descs.add(desc); } } } return (IViewDescriptor[]) descs.toArray(new IViewDescriptor[descs .size()]); } /* * (non-Javadoc) * * @see org.eclipse.ui.menus.IWorkbenchContribution#initialize(org.eclipse.ui.services.IServiceLocator) */ public void initialize(IServiceLocator serviceLocator) { locator = serviceLocator; } protected IWorkbenchWindow getWindow() { if(locator == null) return null; IWorkbenchLocationService wls = (IWorkbenchLocationService) locator .getService(IWorkbenchLocationService.class); if (window == null) { window = wls.getWorkbenchWindow(); } if (window == null) { IWorkbench wb = wls.getWorkbench(); if (wb != null) { window = wb.getActiveWorkbenchWindow(); } } return window; } /* * (non-Javadoc) * * @see org.eclipse.jface.action.ContributionItem#dispose() */ public void dispose() { if (currentManager != null && currentManager.getSize() > 0) { IMenuService service = (IMenuService) locator .getService(IMenuService.class); if (service != null) { service.releaseContributions(currentManager); } currentManager.removeAll(); currentManager = null; } if (getParent() instanceof MenuManager) { ((MenuManager) getParent()).removeMenuListener(menuListener); } actions.clear(); window=null; locator=null; } }